#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "SDL/SDL.h"
#include <netdb.h>

#define HEARTBEATS_PORT 36637
#define SERVER_PORT 36666
#define BUFLEN 512
static int count = 0;
static struct itimerval oldtv;
static struct itimerval oldtv_heartbeat;
char arg0[64];
char arg1[8];
char arg2[8];
char arg3[8];

int own_port = 0;


struct seg_arguments
{
  unsigned int minval;	//min number of segments
  unsigned int maxval;	//max number of segments
  unsigned int thbeat;	//heartbeat time
}arg;


struct in_addr localInterface;
struct sockaddr_in kill_recv_group;
struct sockaddr_in kill_last_groupSock;
struct sockaddr_in kill_all_groupSock;
struct sockaddr_in heartbeat_group_sock, s_addr_in;

pid_t srv_listen = -1;
int maxtime = 0;


//global variables for all the child processes
pid_t heartbeat_pid = -1 ;
pid_t seglogic_pid = -1 ;
pid_t display_pid = -1 ;
	
char kill_msg;
struct sockaddr_in si_other;
struct sockaddr_in group_sock;
char buf[BUFLEN]="0";
int socket_heartbeat=0;
FILE *fp = NULL;  //the log file
int seg_cnt = 0;
char seg[1024]="\0";
char logbuf[1024]="\0";
char gates_adr[28][20] = {	//to be replaced with real lab nodes addresses
	"tile-0-0.local", 
	"tile-0-1.local", 
	"tile-0-2.local", 
	"tile-0-3.local",
	"tile-1-0.local", 
	"tile-1-1.local", 
	"tile-1-2.local",
	"tile-1-3.local", 
	"tile-2-0.local", 
	"tile-2-1.local", 
	"tile-2-2.local",
	"tile-2-3.local", 
	"tile-3-0.local", 
	"tile-3-1.local",
	"tile-3-2.local",
	"tile-3-3.local", 
	"tile-4-0.local", 
	"tile-4-1.local", 
	"tile-4-2.local",
	"tile-4-3.local", 
	"tile-5-0.local", 
	"tile-5-1.local",
	"tile-5-2.local", 
	"tile-5-3.local",
	"tile-6-0.local", 
	"tile-6-1.local", 
	"tile-6-2.local", 
	"tile-6-3.local"	};



void set_timer()
{
	struct itimerval itv;
	itv.it_interval.tv_sec = 1;
	itv.it_interval.tv_usec = 0;
	itv.it_value.tv_sec = 1;
	itv.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &itv, &oldtv);
}

void signal_handler(int m)
{

	if (count >= maxtime) kill(srv_listen, SIGKILL); 
	else count++;
}
int get_app_name(char *p, char *pname)
{
	char *q, *name;
	int len = 0, lenp = 0;
	q = p;
	len = strlen(q);
	lenp = strlen(p);
	q = q + len -1;
	
	while( *q != '/' )
	{
		q--;
		if (strlen(q) == strlen(p))
		{
			strcpy(pname, q);
			return 0;
		}
	}
	strcpy(pname, q+1);
	return 0;
}
int loginfo(char *pstr)
{
	time_t lt;
	char *ptm ;
	char buf[1024];
	int i, cnt= 0;
	struct tm *p;
	lt = time(NULL);
	p = localtime(&lt);
	ptm = ctime(&lt);
	
	char hostname[1024]="";

	gethostname(hostname, 1024);

	sprintf(buf, "[%s]%d-%d-%d %d:%d:%d %s\n", hostname, 1900+p->tm_year, 1 + p->tm_mon, p->tm_mday,  p->tm_hour, p->tm_min, p->tm_sec, pstr);
	
	for ( i = 0; buf[i] != '\0'; i++ ) 
	{
		cnt++;
	}
	fwrite(buf,cnt, 1, fp);	
	i = fflush(fp);
	return 0;
}

int hostname_to_ip(char * hostname , char* ip)
{
    struct hostent *he;
    struct in_addr **addr_list;
    int i;

    if ( (he = gethostbyname( hostname ) ) == NULL)
    {
        // get the host info
        loginfo("gethostbyname");
        return -1;
    }
    addr_list = (struct in_addr **) he->h_addr_list;
    for(i = 0; addr_list[i] != NULL; i++)
    {
        //Return the first one;
        strcpy(ip , inet_ntoa(*addr_list[i]) );
        return 0;
    }
    return -1;
}


int kill_the_last(char *kill_addr, char *kill_port)
{
	//sending kill_all signal to everyone else by broadcast to port 36666
	//here we have a client
	char buf[6];
	struct sockaddr_in si_other;
  	int  s_kill_last, i, slen=sizeof(si_other);

  	if ((s_kill_last=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    {
		loginfo("socket in kill_the_last");
		return 1;
	}
	bzero(&si_other, sizeof(struct sockaddr_in));
	si_other.sin_family = AF_INET;
	si_other.sin_port = htons(atoi(kill_port));
	si_other.sin_addr.s_addr = inet_addr(kill_addr);
	//itoa(own_port, buf, 10);
	sprintf(buf, "%d", own_port);	
	//sprintf(buf, "SLF"); 
        if (sendto(s_kill_last, buf, 512, 0, (struct sockaddr*)&si_other, sizeof(si_other) )==-1)
	{
		sprintf(logbuf, "Couldn't send the kill message to %s:%s\n", kill_addr, kill_port);	
		loginfo(logbuf);
		return 1;
	}
	return 0;
}


int spread_the_worm(int gate_num)
{

        struct sockaddr_in servaddr, client_addr;
        int sockfd_spread, source_fd;
        char hostname[1024], iobuffer[1024];
        struct hostent *phost = NULL;
	char filename[1024], segment_path[1024];
	int j,num, ret, size = 0;
	char pname[BUFLEN];
	char *pprogram;
	char path[1024], arg[1024];
	int errno;
   
	sprintf(logbuf, "Sending file to gate nr %i: %s, port 36000\n", gate_num, gates_adr[gate_num]);
	loginfo(logbuf);
	////////////////////////////////////////	
	//sending file socket client connection	needed here
	////////////////////////////////////////
	
        sockfd_spread = socket( AF_INET, SOCK_STREAM, 0);
        if ( sockfd_spread < 0)
        {
                loginfo("socket err in spread");
                return 1;
        }
	
	bzero(&client_addr, sizeof(client_addr));
	client_addr.sin_family = AF_INET;
	client_addr.sin_addr.s_addr = htons(INADDR_ANY);
	client_addr.sin_port = htons(0);

        servaddr.sin_family = AF_INET;

        //inet_aton( "127.0.0.1", &servaddr.sin_addr);
	//servaddr.sin_addr.s_addr = inet_aton( "127.0.0.1" );
        servaddr.sin_port = htons(36600);

        //send to server by hostname
    
	phost = gethostbyname(gates_adr[gate_num]);

        
	sprintf(logbuf,"gate addr = %s", inet_ntoa( *(struct in_addr*)phost->h_addr_list[0]));
	loginfo(logbuf);
        servaddr.sin_addr = (*(struct in_addr*)phost->h_addr_list[0]);
		sprintf(logbuf,"sin_family = %d, sin_port = %d, sin_addr = %s, \n", servaddr.sin_family, servaddr.sin_port, inet_ntoa(servaddr.sin_addr));
		loginfo(logbuf);
        if ( connect( sockfd_spread, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
        {
                sprintf(logbuf, "Connect err: %d\n", errno);
		loginfo(logbuf);
                
		return -1;
        }
	
	//send the three arguments
	sprintf(arg, "%s%s%s", arg1, arg2, arg3);
	sprintf(logbuf, "arg list si %s, %s, %s",arg1, arg2, arg3);	
	loginfo(logbuf);
	ret = write(sockfd_spread, arg, sizeof(arg) );
        if ( -1 == ret)
        {
                sprintf(logbuf,"write err %d\n", errno);
                loginfo(logbuf);
                return -1;
        }


	getcwd(path, 1024);
	sprintf(logbuf,"getcwd path = %s\n", path);
	loginfo(logbuf);
	ret = get_app_name(arg0, pname);
	if ( ret != 0)
	{
		loginfo("get_app_name failed");
		return -1;
	}

	sprintf(filename, "%s/%s", path, pname);
	sprintf(logbuf,"filename is %s, and pname is %s\n", filename, pname);
	loginfo(logbuf);
	
	if ((source_fd = open(filename, O_RDONLY, 0) ) == -1)
        {
                loginfo("file open err\n");
                return -1;
        }
   

	while ( (num = read(source_fd, iobuffer, sizeof(iobuffer))) > 0)
        {
                write(sockfd_spread, iobuffer, num);
		sprintf(logbuf, "num is %d", num);
		loginfo(logbuf);
		size += num;
        }
	sprintf(logbuf,"sent data: %6d bytes\n", size);
	loginfo(logbuf);
	close(source_fd);
        close(sockfd_spread);
	loginfo("send file success");
	
	
	return 0;
}

int display()
{
	SDL_Surface *screen, *logo;
	int i = 0, j;
	char dbuf[512];
	SDL_Rect logoRect;
	atexit(SDL_Quit);

	if( SDL_Init(SDL_INIT_VIDEO) < 0 ) 
	{
		exit(1);
	}
	logo = SDL_LoadBMP("/home/inf3200/students/wzh000/sdllogo.bmp");
	if ( logo == NULL)
	{
		exit(1);
	}
	SDL_ShowCursor(SDL_DISABLE);

	i = rand()%1024;

	j = rand()%768;
	sprintf(dbuf, "SDL_VIDEO_WINDOW_POS=%d,%d", i, j);
	SDL_putenv(dbuf);	
	screen = SDL_SetVideoMode(123,67,16,SDL_HWSURFACE|SDL_DOUBLEBUF);	
		
	SDL_BlitSurface(logo , NULL , screen , &logoRect );
	SDL_Flip(screen);
	while(1)
	{
	}
	return 0;
}

int kill_me()
{
	//killing all own processes and itself on demand

	kill(heartbeat_pid,SIGKILL);
	kill(seglogic_pid,SIGKILL);
	kill(display_pid,SIGKILL);
	exit(0); 		
	return 0;	//i don't see much sense in this line, but it was requested

	//maybe we also should add some cleaning functions before
}


int kill_all()
{
	//sending kill_all signal to everyone else by broadcast to port 366666
	char kbuf[512];
	struct in_addr localInterface;

  	int  s_kill_all, i, slen=sizeof(si_other);
  	int ilen = 0;
	int len, ret;
	char hostname[BUFLEN], ip[BUFLEN];

  	if ((s_kill_all=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    	loginfo("socket");
	
	memset((char *) &kill_all_groupSock, 0, sizeof(kill_all_groupSock));
	kill_all_groupSock.sin_family = AF_INET;
	kill_all_groupSock.sin_addr.s_addr = inet_addr("226.1.1.1");
	kill_all_groupSock.sin_port = htons(36666);
	
	gethostname(hostname, BUFLEN);
	if( -1 == (ret = hostname_to_ip(hostname, ip)) )
	{
		loginfo("hostname_to_ip in send_heartbeat");
		return 'N';
	}	
	
    localInterface.s_addr = inet_addr(ip);
	if(setsockopt(s_kill_all, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface)) < 0)
	{
		loginfo("Setting local interface error");
		return 1;
	}	

	sprintf(kbuf, "ALL");	
        len = sizeof( struct sockaddr);
        if (sendto(s_kill_all, kbuf, 512, 0, (struct sockaddr*)&kill_all_groupSock, sizeof(kill_all_groupSock) )==-1)
		{
			loginfo("sendto() in kill_all");
			return 1;
		}
	
	kill_me();
	return 0;

}

int kill_receive()
{

	//receiving kill signal (A/ALL - all, S/SLF - self)

	struct sockaddr_in si_me;
	struct ip_mreq kill_recv_group;
	char hostname[BUFLEN], ip[BUFLEN];
	int ret;
	int s_recv;
	int slen = sizeof(struct sockaddr);
	int errno;

	char kill_tab[512];

	if ((s_recv=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)	
	{
		loginfo("socket in kill_receive err");
		exit (1);
	}
	
	memset((char *) &si_me, 0, sizeof(si_me));
	
	si_me.sin_family = AF_INET;
	si_me.sin_port = htons(SERVER_PORT);
	si_me.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(s_recv, (struct sockaddr *)&si_me, sizeof(si_me))==-1)
	{
	  sprintf(logbuf,"bind err in kill_receive, errno = %d", errno);
	  loginfo(logbuf);
	  return 'N';
	}
	kill_recv_group.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
	gethostname(hostname, BUFLEN);
	if( -1 == (ret = hostname_to_ip(hostname, ip)) )
	{
		loginfo("hostname_to_ip in send_heartbeat");
		return 'N';
	}	
	
    kill_recv_group.imr_interface.s_addr = inet_addr(ip);
    if(setsockopt(s_recv, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&kill_recv_group, sizeof(kill_recv_group)) < 0)
    {
        loginfo("Adding multicast group error");
        close(s_recv);
        return 'N';
    }
	loginfo("before recvfrom in kill_receive");
	while (recvfrom(s_recv, kill_tab, 512, 0, (struct sockaddr *)&si_other, &slen)!=-1) 
	{
		sprintf(logbuf,"Received packet from %s:%d\nData: %s\n\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), kill_tab);
        	loginfo(logbuf);

        	if (kill_tab[0] == 'A' && kill_tab[1] == 'L' && kill_tab[2] == 'L') kill_msg = 'A';
        	else if  (atoi(kill_tab)==own_port) kill_msg = 'S';
		else return 1;

        	//in message we should receive: char 'A' if killing all, 'S' if killing self
       		 switch (kill_msg)
        	{
                case 'A':               //handling kill_all
                        kill_all();
                        break;


                case 'S':       //handling kill_me
                        kill_me();
                        break;

                default: break;
        	}
		close(s_recv);

	}
	
	loginfo("recvfrom err in kill_receive");

	return 1;
}


void set_timer_heartbeat()
{	
	struct itimerval itv;
	itv.it_interval.tv_sec = 1;
	itv.it_interval.tv_usec = 0;
	itv.it_value.tv_sec = 1;
	itv.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &itv, &oldtv_heartbeat);
}

void signal_handler_heartbeat(int m)
{
	int len, ilen;
	count ++;
	len = sizeof( struct sockaddr);
	ilen = sizeof( s_addr_in);
	if (sendto(socket_heartbeat, buf, BUFLEN, 0, (struct sockaddr*)&heartbeat_group_sock, sizeof(heartbeat_group_sock) )==-1)
	{
		loginfo("sendto() in signal_handler_heartbeat");
	}
	getsockname(socket_heartbeat,(struct sockaddr *)&s_addr_in,&ilen);
	own_port = ntohs(s_addr_in.sin_port);
	sprintf(logbuf, "heartbeat port %d", own_port);
	loginfo(logbuf);
}


int send_heartbeat()
{

	struct sockaddr_in si_other;
	struct in_addr localInterface;

	int ret;
	char  ip[BUFLEN], hostname[BUFLEN];
	char loopch = 1;

		
	if ((socket_heartbeat=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    	loginfo("socket err in send_heartbeat");
	
	memset((char *) &heartbeat_group_sock, 0, sizeof(heartbeat_group_sock));
	heartbeat_group_sock.sin_family = AF_INET;
	heartbeat_group_sock.sin_addr.s_addr = inet_addr("227.1.1.1");
	heartbeat_group_sock.sin_port = htons(36667);
	//updating the global value: some function = own_port;
	
	gethostname(hostname, BUFLEN);
	if( -1 == (ret = hostname_to_ip(hostname, ip)) )
	{
		loginfo("hostname_to_ip in send_heartbeat");
		return 1;
	}
	
	localInterface.s_addr = inet_addr(ip);
	
	if(setsockopt(socket_heartbeat, IPPROTO_IP, IP_MULTICAST_IF, (char *)&localInterface, sizeof(localInterface)) < 0)
	{
		loginfo("Setting local interface error");
		return 1;
	}	
	else
	{
		loginfo("Setting the local interface...OK\n");
	}
	
	signal(SIGALRM, signal_handler_heartbeat);
	set_timer_heartbeat();
	while(count < 10000)
	{
	}

	close(socket_heartbeat);
	return 0;
}

int main(int argc, char *argv[])
{

	unsigned int seg_counter = 0;
	unsigned int gate_num;


	int i, errno; 
	int segment_already_stored = 0;
	int ret;
	struct sockaddr_in si_me, si_other;
	int s, slen=sizeof(si_other);
	char mbuf[512];
	char cport[5];
	char pname[BUFLEN];
	char hostname[BUFLEN], ip[BUFLEN];
	struct ip_mreq recv_group;
	FILE *fpzhangwei;
	fpzhangwei = fopen("/tmp/wzh000/zhangwei", "a+");
	fclose(fpzhangwei);
	gethostname(hostname, BUFLEN);
	if( -1 == (ret = hostname_to_ip(hostname, ip)) )
	{
		fpzhangwei = fopen("/tmp/wzh000/host_2_ip", "a+");
	        fclose(fpzhangwei);

		exit (0);
	}	
	if ( argc != 4 )
	{
		fpzhangwei = fopen("/tmp/wzh000/argc", "a+");
	        fclose(fpzhangwei);

		exit(0);
	}

	arg.minval = atoi(argv[1]);
	arg.maxval = atoi(argv[2]);
	arg.thbeat = atoi(argv[3]);
	strcpy(arg0, argv[0]);
	strcpy(arg1, argv[1]);
	strcpy(arg2, argv[2]);
	strcpy(arg3, argv[3]);
	if (arg.minval > arg.maxval)
	{
		fpzhangwei = fopen("/tmp/wzh000/minval", "a+");
        fclose(fpzhangwei);

		exit(0);
	}
	

	srand (time(NULL));
	char *segments_adr[10*arg.maxval][0]; 
	char *segments_port[10*arg.maxval][0]; 
	maxtime = arg.maxval*10;
	ret = get_app_name(argv[0], pname);
	
	if ( ret != 0)
	{
		fpzhangwei = fopen("/tmp/wzh000/get_app_name", "a+");
        	fclose(fpzhangwei);

		exit (EXIT_FAILURE);
	}

	sprintf(hostname, "/tmp/wzh000/%s.log", pname);
	remove(hostname);
	fp = fopen( hostname, "a+");
	if ( NULL == fp)
	{
		fpzhangwei = fopen("/tmp/wzh000/openfile", "a+");
	        fclose(fpzhangwei);

		exit (EXIT_FAILURE);
	}    
	loginfo("hello");
	//all the things this main function should do, making child processes and stuff

	heartbeat_pid = fork();
	//printf("heartbeat pid %d", heartbeat_pid);
	if (heartbeat_pid == 0)
	{
	
		
		//executing the heartbeat function
		fpzhangwei = fopen("/tmp/wzh000/zhangwei2", "a+");
        	fclose(fpzhangwei);
		int ret;
		ret = send_heartbeat();

	}

	else if (heartbeat_pid < 0) 
	{

		
		loginfo("Failed to create the heartbeat process");
		
	}
	
	
	else 
	{
		
		//back in the main process code 
		fpzhangwei = fopen("/tmp/wzh000/zhangwei3", "a+");
        fclose(fpzhangwei);
		display_pid = fork();
                if (display_pid == 0)
                {
                        display();
                }

                else if (display_pid < 0)
                {
                        
                        loginfo("Failed to create the display process");
                }
                else
                {
		
	
			seglogic_pid = fork();
	
			if (seglogic_pid == 0)
			{
	
				//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				//executing the seglogic function
				//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

				while(1)
				{	//infinite listening + killing/creating

					for(i=0; i<10*arg.maxval; i++)
					{		
						segments_adr[i][0] = "\0";
						segments_port[i][0] = "\0";
					}


					
					seg_counter = 0;
					count = 0;

					signal(SIGALRM, signal_handler);
					set_timer();
					sprintf(logbuf, "arg.thbeat = %d", arg.thbeat);
					loginfo(logbuf);	
					while(count < 10*arg.thbeat) 
					{
						////////////////////////////////////////
						//waiting for incoming heartbeats (server connection)
						////////////////////////////////////////
			
					     srv_listen = fork();
					     if ( srv_listen == 0)
					     {
						if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)	
						{
							sprintf(logbuf,"socket err, errno %d", errno);
							loginfo(logbuf);
							exit(1);
						}

						//REUSE THINGS	
						int reuse = 1;


						



						if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
						{
							sprintf(logbuf,"Setting SO_REUSEADDR error. errno = %d", errno);
							loginfo(logbuf);
							close(s);
							exit(1);
						}
						else
						{
							//loginfo("Setting SO_REUSEADDR...OK. - server\n");
													
						}



	
						memset((char *) &si_me, 0, sizeof(si_me));
						si_me.sin_family = AF_INET;
						si_me.sin_port = htons(HEARTBEATS_PORT);
						si_me.sin_addr.s_addr = htonl(INADDR_ANY);
						if (bind(s, (struct sockaddr *)&si_me, sizeof(si_me))==-1) 
						{
							loginfo("bind");
							close(s);
							exit(1);
						}
						recv_group.imr_multiaddr.s_addr = inet_addr("227.1.1.1");
					        recv_group.imr_interface.s_addr = inet_addr(ip);
						if(setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&recv_group, sizeof(recv_group)) < 0)
						{
							sprintf(logbuf,"Adding multicast group error, errno = %d\n", errno);
							loginfo(logbuf);
							close(s);
							exit(1);
						}
						

						if (recvfrom(s, mbuf, 512, 0, (struct sockaddr *)&si_other, &slen)==-1) 
						{
							loginfo("recvfrom()");
							exit (1);
						}
						sprintf(logbuf, "Received packet from %s:%d\nData: %s\n\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port),mbuf);
						loginfo(logbuf);

	    					sprintf(cport, "%d", ntohs(si_other.sin_port));

						for(i=0; i<seg_counter; i++) 
						{
							if (strcmp(inet_ntoa(si_other.sin_addr), segments_adr[i][0])==0)
							{
								if(strcmp(cport, segments_port[i][0])==0)
								{
									segment_already_stored = 1; 
									break;
								}		
							} 	
						}

						if(segment_already_stored == 0) 
						{
							segments_adr[seg_counter][0] = inet_ntoa(si_other.sin_addr);
							segments_port[seg_counter][0] = cport;
							seg_counter++;
						}
					
						close(s);

					      }////////
					}
					

				loginfo("Starting the kill/create block:");

				if (seg_counter < arg.minval) 
				{
					//creating new segments block
				
					for(seg_counter; seg_counter < arg.minval; seg_counter++)
					{
						gate_num = rand() %28;
						spread_the_worm(gate_num);
					}
				
				}
			
				//loginfo("Updating seg_counter, address and port for test purposes\n");
				//seg_counter = 10; 
				

				if (seg_counter > arg.maxval)
				{
					//killing too many segments block

					while(seg_counter > arg.maxval)
					{
						sprintf(logbuf, "Killing segment nr %i:\n", seg_counter);
						loginfo(logbuf);
						kill_the_last(segments_adr[seg_counter][0], segments_port[seg_counter][0]);
						seg_counter--;
					
					}
				}		
			  }
			}
		
			else if (seglogic_pid < 0) 
			{
		  
				loginfo("Failed to create segment logic process\n");
			}		
	
			else
			{
				//back in the main process code 
				
				//main process module - suicide part
			
					//this is the killing segments part
					kill_receive();
	
					//in message we should receive: char 'A' if killing all, 'S' if killing self
					switch (kill_msg)
					{
						case 'A':		//handling kill_all
							kill_all();
							break;
							
		
						case 'S':    	//handling kill_me
							kill_me();
							break;

						default: break;
					}

			}
			

		}
	}
	return 0;

}
